package microgsr;

// GSR communicates with GSR 0.1 board


import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.DateFormat;
import java.util.Calendar;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import microgsr.GSRDevice.pulse;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class microGSR_realtime implements ActionListener, KeyListener, WindowListener {
	GSRDevice GSR = new GSRDevice();

	String VERSION="DDD";

	long pageptr;
	
	//double ymax = 2000;
	double dx = 60;
	
	JFreeChart chart1;
	XYSeriesCollection dataset;
	XYSeries gsr_series, filt_series;
	
	protected void finalize()
	{
		//ToggleConnected();

		System.out.println("Close HID");
		GSR.Disconnect();
	}
	
		
	microGSR_realtime() throws InterruptedException
	{		
		dataset = new XYSeriesCollection();
		
		gsr_series = new XYSeries("SC");	
		filt_series = new XYSeries("Filt");

	    dataset.addSeries(gsr_series);
	    dataset.addSeries(filt_series);

	    
//      Generate the graph
        
		chart1 = ChartFactory.createScatterPlot("", // Title
	                "time", // x-axis Label
	                "Skin Conductance [uSiemens]", // y-axis Label
	                dataset, // Dataset
	                PlotOrientation.VERTICAL, // Plot Orientation
	                true, // Show Legend
	                false, // Use tooltips
	                false // Configure chart to generate URLs?
	            );
		
		
		//chart1.getXYPlot().getRangeAxis().setAutoRange(false);
		//chart1.getXYPlot().getRangeAxis().setRange(0, ymax);
		// gsr_series.setMaximumItemCount(10000);
		
		
		ValueAxis domain = chart1.getXYPlot().getDomainAxis();
		
		chart1.getXYPlot().getRangeAxis().setAutoRangeMinimumSize(1);
		
		domain.setFixedAutoRange(dx);
		
		XYLineAndShapeRenderer r1 = new XYLineAndShapeRenderer();
		
		//DateAxis domain2 = (DateAxis) chart1.getXYPlot().getDomainAxis();
		
		chart1.getXYPlot().setRenderer(0, r1);
		        
		chart1.setRenderingHints( new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ) );
		
        // GSR        
	    //r1.setSeriesShape(0, ShapeUtilities.createUpTriangle(3));
	    r1.setSeriesPaint(0, Color.blue);
	    r1.setSeriesShapesVisible(0, false);
	    
	    Stroke stroke = new BasicStroke(1);
	    r1.setSeriesStroke(0, stroke);
	    
	    r1.setSeriesPaint(1, Color.yellow);
	    r1.setSeriesShapesVisible(1, false);
	    	    
        ChartPanel p1 = new ChartPanel(chart1);
        
        //p1.setMinimumSize(new Dimension(300,300));        
        //p2.setMinimumSize(new Dimension(300,300));
        //p3.setMinimumSize(new Dimension(300,300));
        //p4.setMinimumSize(new Dimension(300,300));
        
        JFrame chart_frame = new JFrame(VERSION);
        chart_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        chart_frame.addWindowListener(this);

        chart_frame.setLayout(new BorderLayout());
        
	        
        JPanel panel = new JPanel();
        //panel.setLayout(new GridLayout(0,2));
        
        panel.setMinimumSize(new Dimension(300,300));
        
        panel.add(p1);
        
        chart_frame.add(panel, BorderLayout.CENTER);
        
        JButton bErase = new JButton("Erase");        
        JButton bSetClock = new JButton("Set clock");        
        JButton bLoad = new JButton("Load");
        JButton bXScaleInc = new JButton("X zoom in");
        JButton bXScaleDec = new JButton("X zoom out");

        bErase.setActionCommand("erase");
        bSetClock.setActionCommand("setclock");
        bLoad.setActionCommand("load");
        bXScaleInc.setActionCommand("xin");
        bXScaleDec.setActionCommand("xout");
        
        bXScaleInc.addActionListener(this);
        bXScaleDec.addActionListener(this);
        bLoad.addActionListener(this);        
        bErase.addActionListener(this);
        bSetClock.addActionListener(this);

        
        //chart_frame.addKeyListener(this);
        //p.addKeyListener(this);

        JPanel bpanel = new JPanel();
        chart_frame.add(bpanel, BorderLayout.SOUTH);
       
        bpanel.add(bErase);
        bpanel.add(bSetClock);        
        bpanel.add(bLoad);

        bpanel.add(bXScaleInc);
        bpanel.add(bXScaleDec);

        chart_frame.setVisible(true);
        chart_frame.pack();		
				
		byte[] buff = new byte[64];
		
		double f = 0;
				
	    double start = System.currentTimeMillis()/1000.0;
	    
	    int res = GSR.Connect();
		if(res==-1) {
			System.out.println("Connect error");
			JOptionPane.showMessageDialog(null, "Cannot find GSR device. Please connect it first.");
			System.exit(0);
		}
		
	    
		if(res==-2) {
			JOptionPane.showMessageDialog(chart_frame, "Device is already connected to a running program," +
					"\n or another program was not properly disconnected. \n\n Close the other program or switch off and back on device.");
			System.exit(0);
		}
		
	    String version = GSR.ReadVersion();
	    if(version.compareTo(VERSION)!=0) {
			//JOptionPane.showMessageDialog(chart_frame, "Version mismatch! \nDevice="+version+" Program="+VERSION);
			//System.exit(0);
	    }
	    System.out.println(version);
	    
	    double avg_gsr = -10;
	    
	   	    
	    pageptr = GSR.ReadPageptr();
	    //GSR.PageWrite();
	    //GSR.ReadStatusReg();
	    	    
	    //GSR.SetRTC();
	    
	    //while(avg_gsr<0) {
	       GSR.ReadRTC();
	    //   Thread.sleep(60000);
	    //}

		int n=0;
		double d= 0;		
		long lastts=0;
		int nn=0;
		
		GSR.ReadMem(256*256);
		GSR.ReadMem(256*256+10);
		
if(true) while(true) Thread.sleep(1000);
	   	    

	    n = 0;
		do {
			/*
			buff[1] = (byte) 0x80;
			if (!myHID.IntSendOutputReport(buff))
				System.out.println(" Send failed");		
			else System.out.println(" Send OK");
			*/
			
			
			try {
				Thread.sleep(50);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		    double dt = System.currentTimeMillis()/1000.0 - start;			

            long gsr=0;
            gsr = GSR.ReadGSR();
            
            //GSR.ReadMem();
            GSR.ReadRTC();

            //if(gsr>=Math.pow(2, 21)) gsr=0;
            
			double alpha;
			alpha = 100.0/(100+680.0);
			
			double R = 100e3;

			
			double A = 1.0*gsr / Math.pow(2, 21);
			double G = A / alpha / R * 1e6;
					    
			
			
			gsr_series.add(dt, G);
					    
		    System.out.println("GSR:"+gsr+" uH="+G+" A="+A);

			n++;
					 
		} while(true);
		
		//System.exit(0);
	}
	
	public static void main(String[] args) throws InterruptedException 
	{
		new microGSR_realtime();
	}

	void load() {
		long n=0;
		double d= 0;		
		long lastts=0;
		int nn=0;
		
		double f=0;
		
		System.out.println("Load");
		
		//XYSeries series = new XYSeries("SC");
	    //dataset.addSeries(gsr_series);		

		long t1 = System.currentTimeMillis();		
		
		dataset.removeSeries(gsr_series);
		
		for(n=0; n<65536*128; n+=256) {
	    	ByteBuffer bb;
	    	bb = GSR.ReadPage(n);
	    				
	    	nn++;
	    	
	    	// LEHET HOGY A JAVA KOD ROSSZ??????????????????????????????????
	    		    	
			if(bb.get(0)==-1 && bb.get(1)==-1) {
				System.out.println("End "+n);
				break;
			}
			
			
			long ts = GSR.GetTimestamp(bb); 
			if(nn%100==0) {
				double rate = 1000.0*nn / (System.currentTimeMillis() - t1);
				System.out.println("rate="+rate+" n="+n);
				nn=0;
				t1 = System.currentTimeMillis();		
			}
			
			
			if(ts-lastts>40000) {
				System.out.println("Marker");

				Marker m = new ValueMarker(d);
				chart1.getXYPlot().addDomainMarker(m);
				
				f=0;
			}
						
			while(bb.hasRemaining()) {
				int gsr = bb.getInt();
				//System.out.println(gsr);
				
				double alpha;
				alpha = 100.0/(100+680.0);
				
				double R = 100e3;


				double A = 1.0*gsr / Math.pow(2, 21);
				double G = A / alpha / R * 1e6;
				
				
				if(G>0.01 && G<100) {
					if(f==0) f=G;
					
					double aa = 0.01;
					f = aa*G + (1-aa)*f;
						    				
					gsr_series.add(d, G);				
					//filt_series.add(d, G-f);
				}
				
				d+= 0.125;

			}
			

			lastts = ts;
	    }
		
		dataset.addSeries(gsr_series);

	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		
		System.out.println("Command "+arg0.getActionCommand());
		
		if(arg0.getActionCommand().compareTo("xin")==0) {
			dx *= 0.5;
			chart1.getXYPlot().getDomainAxis().setFixedAutoRange(dx);
		}

		if(arg0.getActionCommand().compareTo("xout")==0) {
			dx *= 2;
			chart1.getXYPlot().getDomainAxis().setFixedAutoRange(dx);
		}

		if(arg0.getActionCommand().compareTo("erase")==0) {
			GSR.Erase();
		}

		if(arg0.getActionCommand().compareTo("load")==0) {
			load();
		}

		if(arg0.getActionCommand().compareTo("setclock")==0) {
			GSR.SetRTC();
		}

	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Pressed "+arg0.getKeyChar());

	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Typed "+arg0.getKeyChar());
	}


	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void windowClosing(WindowEvent arg0) {
		// TODO Auto-generated method stub
	
		GSR.Disconnect();
		System.out.print("Closing");
	}


	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void windowOpened(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

}

